// blockchain.go
package main

// BlockChain 模拟区块链作为去中心化验证者
type BlockChain struct {
	System         *System
	RegisteredCSPs map[string]*CSP // 存储已注册CSP的公钥等信息
}

// NewBlockChain 创建一个新的验证者实例
func NewBlockChain(sys *System) *BlockChain {
	return &BlockChain{
		System:         sys,
		RegisteredCSPs: make(map[string]*CSP),
	}
}

// RegisterCSP 模拟CSP在链上注册其公钥
func (bc *BlockChain) RegisterCSP(csp *CSP) {
	bc.RegisteredCSPs[csp.Name] = csp
}

// Verify 对两个CSP的证明进行一致性验证
func (bc *BlockChain) Verify(proofA, proofB *Proof, nameA, nameB string) bool {
	cspA, okA := bc.RegisteredCSPs[nameA]
	cspB, okB := bc.RegisteredCSPs[nameB]
	if !okA || !okB || proofA == nil || proofB == nil {
		return false
	}
	pkA, pkB := cspA.Pk, cspB.Pk

	// LHS numerator: e(βA * g^θA, pkB)
	baseLHSNum := bc.System.PublicPar.Pairing.NewG1().PowZn(bc.System.PublicPar.G, proofA.Theta)
	baseLHSNum.Mul(baseLHSNum, proofA.Beta)
	lhsNum := bc.System.PublicPar.Pairing.NewGT().Pair(baseLHSNum, pkB)

	// LHS denominator: e(βB * g^θB, pkA)
	baseLHSDen := bc.System.PublicPar.Pairing.NewG1().PowZn(bc.System.PublicPar.G, proofB.Theta)
	baseLHSDen.Mul(baseLHSDen, proofB.Beta)
	lhsDen := bc.System.PublicPar.Pairing.NewGT().Pair(baseLHSDen, pkA)

	lhs := bc.System.PublicPar.Pairing.NewGT().Div(lhsNum, lhsDen)

	// RHS numerator: e(g, ΨA,B)
	psiAB, ok := proofA.Psi[nameB]
	if !ok {
		return false
	}
	rhsNum := bc.System.PublicPar.Pairing.NewGT().Pair(bc.System.PublicPar.G, psiAB)

	// RHS denominator: e(g, ΨB,A)
	psiBA, ok := proofB.Psi[nameA]
	if !ok {
		return false
	}
	rhsDen := bc.System.PublicPar.Pairing.NewGT().Pair(bc.System.PublicPar.G, psiBA)

	rhs := bc.System.PublicPar.Pairing.NewGT().Div(rhsNum, rhsDen)

	return lhs.Equals(rhs)
}
